#pragma once

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

//json版本
// #define MySelf 1

const std::string blank_space_sep = " "; 
const std::string protocol_sep = "\n";

//"x op y" => "len"\n"x op y"\n
std::string Encode(std::string& content) { 
    std::string package = std::to_string(content.size());
    package += protocol_sep;
    package += content;
    package += protocol_sep;
    return package;
}

//"len"\n"x op y"\n => "x op y"
bool Decode(std::string& package, std::string* content) {
    //取第一个\n之前的len，并转为整形
    size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos) return false;
    std::string len_str = package.substr(0, pos);//报头字符串
    size_t len = std::stoi(len_str);//报头表示有效载荷的长度
    //检查整个package的长度。 package = len_str + content_str + 2 (2个\n)
    size_t total_len = len_str.size() + len + 2;
    if (package.size() < total_len) return false;
    
    *content = package.substr(pos + 1, len);
    //从流中获取完一条完整报文后就要移除它，erase 移除报文 
    package.erase(0, total_len);
    return true;
}

class Request {
public:
    Request(int data1, int data2, char oper)
        :x(data1), y(data2), op(oper) {}
    Request() {}
public:
    //struct => string,  "x op y"
    bool Serialize(std::string* out) {
#ifdef MySelf
        //构建报文的有效载荷
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);
        *out = s;
        return true;
#else
        Json::Value root;
        root["x"] = x;
        root["y"] = y;
        root["op"] = op;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;
#endif
    }

    // string => struct 
    bool Deserialize(const std::string& in) { 
#ifdef MySelf
        // 索引: 0 1 2 3 4
        // 字符: 3   +   4
        size_t left = in.find(blank_space_sep);//left是1
        if (left == std::string::npos) return false;
        std::string part_x = in.substr(0, left);

        size_t right = in.rfind(blank_space_sep);//right是3
        if (right == std::string::npos) return false;
        std::string part_y = in.substr(right + 1);

        if (left + 2 != right) return false;
        op = in[left + 1];
        x = std::stoi(part_x);
        y = std::stoi(part_y);
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);
        x = root["x"].asInt();
        y = root["y"].asInt();
        op = root["op"].asInt();
        return true;
#endif        
    }

    void DebugPrint() {
        printf("请求构建完成：%d %c %d = ?\n", x, op, y);
    }
public:
    int x;
    int y;
    char op;
};


class Response {
public:
    Response(int res, int c)
        :result(res), code(c) {}
    Response() {}
public:
    //struct => string  "result code"
    bool Serialize(std::string* out) {
#ifdef MySelf        
        //构建有效载荷
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);
        *out = s;
        return true;
#else
        Json::Value root;
        root["result"] = result;
        root["code"] = code;
        // Json::FastWriter w;
        Json::StyledWriter w;
        *out = w.write(root);
        return true;
#endif  
    }

    //string => struct
    bool Deserialize(const std::string& in) {
#ifdef MySelf        
        size_t pos = in.find(blank_space_sep);//left是1
        if (pos == std::string::npos) return false;
        std::string left = in.substr(0, pos);
        std::string right = in.substr(pos + 1);
        result = std::stoi(left);
        code = std::stoi(right);       
        return true;
#else
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);
        result = root["result"].asInt();
        code = root["code"].asInt();
        return true;
#endif
    }

    void DebugPrint() {
        std::cout << "结果响应完成, result:" << result << ", code:" << code << std::endl << std::endl; 
    }
public:
    int result;
    int code;//0可信；!0是几，表明对应的错误原因
};



// //手写序列化和反序列化
// const std::string blank_space_sep = " "; 
// const std::string protocol_sep = "\n";

// //"x op y" => "len"\n"x op y"\n
// std::string Encode(std::string& content) { 
//     std::string package = std::to_string(content.size());
//     package += protocol_sep;
//     package += content;
//     package += protocol_sep;
//     return package;
// }

// //"len"\n"x op y"\n => "x op y"
// bool Decode(std::string& package, std::string* content) {
//     //取第一个\n之前的len，并转为整形
//     size_t pos = package.find(protocol_sep);
//     if (pos == std::string::npos) return false;
//     std::string len_str = package.substr(0, pos);//报头字符串
//     size_t len = std::stoi(len_str);//报头表示有效载荷的长度
//     //检查整个package的长度。 package = len_str + content_str + 2 (2个\n)
//     size_t total_len = len_str.size() + len + 2;
//     if (package.size() < total_len) return false;
    
//     *content = package.substr(pos + 1, len);
//     //从流中获取完一条完整报文后就要移除它，erase 移除报文 
//     package.erase(0, total_len);
//     return true;
// }

// class Request {
// public:
//     Request(int data1, int data2, char oper)
//         :x(data1), y(data2), op(oper) {}
//     Request() {}
// public:
//     //struct => string,  "x op y"
//     bool Serialize(std::string* out) {
//         //构建报文的有效载荷
//         std::string s = std::to_string(x);
//         s += blank_space_sep;
//         s += op;
//         s += blank_space_sep;
//         s += std::to_string(y);
//         *out = s;
//         return true;
//     }

//     // string => struct 
//     bool Deserialize(const std::string& in) { 
//         // 索引: 0 1 2 3 4
//         // 字符: 3   +   4
//         size_t left = in.find(blank_space_sep);//left是1
//         if (left == std::string::npos) return false;
//         std::string part_x = in.substr(0, left);

//         size_t right = in.rfind(blank_space_sep);//right是3
//         if (right == std::string::npos) return false;
//         std::string part_y = in.substr(right + 1);

//         if (left + 2 != right) return false;
//         op = in[left + 1];
//         x = std::stoi(part_x);
//         y = std::stoi(part_y);
//         return true;
//     }

//     void DebugPrint() {
//         printf("请求构建完成：%d %c %d = ?\n", x, op, y);
//     }
// public:
//     int x;
//     int y;
//     char op;
// };


// class Response {
// public:
//     Response(int res, int c)
//         :result(res), code(c) {}
//     Response() {}
// public:
//     //struct => string  "result code"
//     bool Serialize(std::string* out) {
//         //构建有效载荷
//         std::string s = std::to_string(result);
//         s += blank_space_sep;
//         s += std::to_string(code);
//         *out = s;
//         return true;
//     }

//     //string => struct
//     bool Deserialize(const std::string& in) {
//         size_t pos = in.find(blank_space_sep);//left是1
//         if (pos == std::string::npos) return false;
//         std::string left = in.substr(0, pos);
//         std::string right = in.substr(pos + 1);
//         result = std::stoi(left);
//         code = std::stoi(right);       
//         return true;
//     }

//     void DebugPrint() {
//         std::cout << "结果响应完成, result:" << result << ", code:" << code << std::endl << std::endl; 
//     }
// public:
//     int result;
//     int code;//0可信；!0是几，表明对应的错误原因
// };